//  File:         Notebook.cpp
//  Author:       Scott Nordmann & Lauren Wallace
//  Description:  Non-inline member function definitions.
#include "Notebook.h"
#include "Note.h"
#include <string>
#include <iostream>
#include <fstream>

using namespace std;

Notebook::Notebook()
{

}
Notebook::Notebook(ifstream& ifsave)
{
	int numNotes = 0;
	int ctr =0;
	Note* tempNote;
	string tempCreator; 
	string tempTitl;
	string tempCont;
	int tempPrio;

	ifsave >> numNotes;
	ifsave.ignore();
	while (ctr != numNotes)
	{
		++ctr;
		getline(ifsave, tempCreator);
		getline(ifsave, tempTitl);
		getline(ifsave, tempCont);
		ifsave  >> tempPrio;
		ifsave.ignore();
		tempNote = new Note(tempCreator, tempTitl, tempCont, tempPrio);
		notes.push_back(tempNote);
	}
}

Notebook::~Notebook()
{
	vector<Note*>::iterator iter;
	for(iter=notes.begin(); iter != notes.end(); ++iter)
	{
		delete *iter;
	}

	notes.clear();
}
void Notebook::shutDown(ofstream& ofsave)
{
	ofsave << notes.size() << endl;
	if (notes.size() != 0)
	{
		vector<Note*>::iterator iter;
		for(iter=notes.begin();iter !=notes.end(); ++iter)
		{
			ofsave << (*iter)->getCreatorName() <<endl;
			ofsave << (*iter)->getTitle() <<endl;
			ofsave << (*iter)->getContent() <<endl;
			ofsave << (*iter)->getPriority() <<endl;
		}
	}
}

void Notebook::createNote(const string& creator)
{
	Note* temp = new Note(creator);

	temp->populate();

	notes.push_back(temp);

}
void Notebook::createNote(Note* not)
{
	notes.push_back(not);
}

Note* Notebook::createMail(const string& creator)
{
	Note* temp = new Note(creator);
	string target;

	temp->populate();

	cout << "Enter Recipient name: ";
	getline(cin, target);
	temp->setSendTo(target);

	return temp;
}


void Notebook::display() 
{
	int ctr=0;
	int choice=0;
	int prio;

	char command = ' ';

	while (toupper(command) != 'M')
	{
		cout << "Browsing The Notebook" << endl << endl;

		cout << "A: Show All Notes" << endl;
		cout << "P: Show Notes by Priority" << endl;
		cout << "M: Notebook Menu" << endl << endl;
		
		cout << "Please enter your selection: ";
		cin >> command;

		switch (toupper(command))
		{
		case 'A':

			allNotes();	

			break;
		
		case 'P':
			
			cout << "Enter Priority (highest" << Note::getMinPriority() << " - " << Note::getMaxPriority() << "lowest): ";
			cin >> prio;

			prio = Note::convertPriority(prio);
			
			priorityNotes(prio);
			
			break;
		
		case 'M':
			break;

		default:
			cout << "Invalid selection." << endl << endl;
			break;
		}

		cout << "Press any key to continue . . .";

		cin.get();

		system("cls");
	}
}

void Notebook::allNotes()
{
	int ctr=0;
	int choice=0;
	vector<Note*>::iterator iter;

	system("cls");
	cout << "All Notes" << endl << endl;
	//
	//display the Summaries of the notes for user selection
	//

	if ( ! ( notes.empty() ) )
	{
		for(iter = notes.begin(), ctr=0; iter != notes.end(); ++iter)
		{	
			++ctr;
			cout << "[" << ctr << "] ";
			(*iter)->displaySummary();
		}
	
		cout << "Which note would you like to view (enter number 1 - " << ctr << ")? ";
		cin >> choice;
		// range checked here- if it's out of bounds put choice in bounds
		if (choice < 1)
			choice = 1;
		if (choice > ctr)
			choice = ctr;
				
		--choice;//decriment choice so that it works with vector
				
		system("cls");
		
		viewNote(  *(notes.at(choice))  );
		
	}
	else
		cout << "there are no notes" << endl;
}

void Notebook::priorityNotes(int prio)
{
	int ctr=0;
	int choice=0;
	
	vector<Note*>::iterator iter;
	vector<Note*> tempnotebook;
	if ( ! ( notes.empty() ) )
	{
		for(iter = notes.begin(), ctr=0; iter != notes.end(); ++iter)
		{
			if (**iter == prio)
			{
				++ctr;
				cout << "[" << ctr << "] ";
				(*iter)->displaySummary();
				tempnotebook.push_back(*iter);
			}
		}
		if (ctr > 0)
		{
			cout << "Which note would you like to view (enter number 1 - " << ctr << ")? ";
			cin >> choice;
			// range checked here- if it's out of bounds put choice in bounds
			if (choice<1)
				choice = 1;
			if (choice > ctr)
				choice = ctr;
					
			--choice;//decriment choice so that it works with vector
					
			system("cls");
			viewNote(  *(tempnotebook.at(choice)) , prio );
		}
		else
		{
			cout << "there are no notes at this priority" << endl;
			cin.get();
		}
	}
	else
	{
		cout << "there are no notes at this priority" << endl;
		cin.get();
	}
}
void Notebook::viewNote(Note& current)
{
	char command = ' ';
	char removechoice = ' ';

	while (toupper(command) != 'M')
	{
		current.display();

		cout << "Viewing a Note" << endl << endl;
		
		cout << "E: Edit Note" << endl;
		cout << "D: Delete Note" << endl;
		cout << "T: View Notes Tags" << endl;
		cout << "A: View Another Note" << endl;
		cout << "M: Notebook Browse Menu" << endl << endl;
		
		cout << "Please enter your selection: ";
		cin >> command;

		switch (toupper(command))
		{
		case 'E':
			system("cls");
			current.edit();		
			break;
		
		case 'D':
			cout << "Are you sure?(Y or N):";
			cin >> removechoice;
			if (toupper(removechoice) == 'Y')
			{
				//TODO:test to see if note was deleted
				deleteNote(current);
				command = 'M';
			}
			break;
		
		case 'T':
			cout << "this notes tags:" << endl;
			current.displayTags();
			cin.ignore();
			cin.get();
			break;
		
		case 'A':
			allNotes();
			command = 'M';
			break;
		
		case 'M':
			break;

		default:
			cout << "Invalid selection." << endl << endl;
			break;
		}
		system("cls");
	}
}
void Notebook::viewNote(Note& current, int prio)
{
	char command = ' ';
	char removechoice = ' ';

	while (toupper(command) != 'M')
	{
		current.display();

		cout << "Viewing a Note" << endl << endl;
		
		cout << "E: Edit Note" << endl;
		cout << "D: Delete Note" << endl;
		cout << "T: View Notes Tags" << endl;
		cout << "A: View Another Note" << endl;
		cout << "M: Notebook Browse Menu" << endl << endl;
		
		cout << "Please enter your selection: ";
		cin >> command;

		switch (toupper(command))
		{
		case 'E':
			system("cls");
			current.edit();		
			break;
		
		case 'D':
			cout << "Are you sure?(Y or N):";
			cin >> removechoice;
			if (toupper(removechoice) == 'Y')
			{
				//TODO:test to see if note was deleted
				deleteNote(current);
				command = 'M';
			}
			break;
		
		case 'T':
			cout << "this notes tags:" << endl;
			current.displayTags();
			cin.ignore();
			cin.get();
			break;
		
		case 'A':
			priorityNotes(prio);
			command = 'M';
			break;
		
		case 'M':
			break;

		default:
			cout << "Invalid selection." << endl << endl;
			break;
		}
		system("cls");
	}
}

bool Notebook::deleteNote(Note& n)
{
	bool found = false;

	vector<Note*>::iterator iter = notes.begin();
	while (!found && iter != notes.end())
	{
		if ((**iter) == n)
		{
		found = true;
		}
		else
		{
		++iter;
		}
	}
	if (found ==true)
	{
		delete (*iter);
		notes.erase(iter);
	}
	return found;
}

bool Notebook::tagNote(Tag &currentTag)
{
	bool tagged;
	Note* currentNote;
	currentNote = addingTagDisplay();
	if (currentNote != NULL)
	{
		currentNote->tag(currentTag);
		tagged = true;
	}
	else 
		tagged = false;
	return tagged;
}

bool Notebook::tagNote(Tag &currentTag ,const string& entryTitle)
{
	bool tagged;
	vector<Note*>::iterator iter;
	Note* currentNote;

	for(iter = notes.begin(); iter != notes.end(); ++iter)
	{	
		if ( (*iter)->getTitle() == entryTitle)
		{
		currentNote = (*iter);
		}
	}
	if (currentNote != NULL)
	{
		currentNote->tag(currentTag);
		tagged = true;
	}
	else 
		tagged = false;
	return tagged;
}

Note* Notebook::addingTagDisplay() 
{
	Note* tagged = NULL;//if the user wants to tag something then the note viewers will return a pointer 
	int ctr=0;
	int choice=0;
	int prio;

	char command = ' ';

	while (toupper(command) != 'M')
	{
		cout << "What Note Would you Like to Tag" << endl << endl;

		cout << "A: Show All Notes" << endl;
		cout << "P: Show Notes by Priority" << endl;
		cout << "M: Notebook Menu" << endl << endl;
		
		cout << "Please enter your selection: ";
		cin >> command;

		switch (toupper(command))
		{
		case 'A':

			tagged = addingTagAllNotes();	

			//if remove is not null then we need to leave notebook and let User delete the note
			if (tagged != NULL)
			{
				command = 'M'; 
			}

			break;
		
		case 'P':
			
			cout << "Enter Priority (highest" << Note::getMinPriority() << " - " << Note::getMaxPriority() << "lowest): ";
			cin >> prio;

			prio = Note::convertPriority(prio);
			
			tagged = addingTagPriorityNotes(prio);
			
			//if remove is not null then we need to leave notebook and let User delete the note
			if (tagged != NULL)
			{
				command = 'M'; 
			}
			break;
		
		case 'M':
			break;

		default:
			cout << "Invalid selection." << endl << endl;
			break;
		}

		system("cls");
	}
	return tagged;
}

Note* Notebook::addingTagAllNotes()
{
	Note* tagged = NULL;
	int ctr=0;
	int choice=0;
	vector<Note*>::iterator iter;

	system("cls");
	cout << "All Notes" << endl << endl;
	//
	//display the Summaries of the notes for user selection
	//

	if (notes.size()==0)
		cout << "there are no notes to display"<<endl;
	else
	{
		for(iter = notes.begin(), ctr=0; iter != notes.end(); ++iter)
		{	
			++ctr;
			cout << "[" << ctr << "] ";
			(*iter)->displaySummary();
		}
	}
	cout << "Which note would you like to tag (enter number 1 - " << ctr << ")? ";
	cin >> choice;
	// range checked here- if it's out of bounds put choice in bounds
	if (choice<1)
		choice = 1;
	if (choice > ctr)
		choice = ctr;
			
	--choice;//decriment choice so that it works with vector
	
	tagged = notes.at(choice);

	system("cls");
	
	return tagged;
			
}

Note* Notebook::addingTagPriorityNotes(int prio)
{
	Note* tagged = NULL;
	int ctr=0;
	int choice=0;
	
	vector<Note*>::iterator iter;
	vector<Note*> tempnotebook;

	for(iter = notes.begin(), ctr=0; iter != notes.end(); ++iter)
	{
		if (**iter == prio)
		{
			++ctr;
			cout << "[" << ctr << "] ";
			(*iter)->displaySummary();
			tempnotebook.push_back(*iter);
		}
	}
	if (ctr > 0)
	{
		cout << "Which note would you like to tag? (enter number 1 - " << ctr << ")? ";
		cin >> choice;
		// range checked here- if it's out of bounds put choice in bounds
		if (choice<1)
			choice = 1;
		if (choice > ctr)
			choice = ctr;
				
		--choice;//decriment choice so that it works with vector
				
		system("cls");
		tagged = tempnotebook.at(choice);
	}
	else
	{
		cout << "there are no notes at priority "<< tagged->convertPriority(prio) << endl ;
		cin.get();
		system("cls");
		tagged = addingTagDisplay();
	}

	return tagged;
}
